import type { HarFile } from '../types/har';

// IndexedDB 数据库配置
const DB_NAME = 'HarAnalysisDB';
const DB_VERSION = 1;
const STORE_NAME = 'harFiles';

// 数据库实例
let db: IDBDatabase | null = null;

/**
 * 初始化 IndexedDB 数据库
 */
export async function initDatabase(): Promise<IDBDatabase> {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);
    
    request.onerror = () => {
      reject(new Error('数据库打开失败'));
    };
    
    request.onsuccess = () => {
      db = request.result;
      resolve(db);
    };
    
    request.onupgradeneeded = (event) => {
      const database = (event.target as IDBOpenDBRequest).result;
      
      // 创建对象存储
      if (!database.objectStoreNames.contains(STORE_NAME)) {
        const store = database.createObjectStore(STORE_NAME, { keyPath: 'id' });
        
        // 创建索引
        store.createIndex('name', 'name', { unique: false });
        store.createIndex('uploadTime', 'uploadTime', { unique: false });
        store.createIndex('size', 'size', { unique: false });
      }
    };
  });
}

/**
 * 获取数据库实例
 */
async function getDatabase(): Promise<IDBDatabase> {
  if (!db) {
    db = await initDatabase();
  }
  return db;
}

/**
 * 保存 HAR 文件到 IndexedDB
 */
export async function saveHarFile(harFile: HarFile): Promise<void> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.put(harFile);
    
    request.onsuccess = () => {
      resolve();
    };
    
    request.onerror = () => {
      reject(new Error('保存文件失败'));
    };
  });
}

/**
 * 批量保存 HAR 文件
 */
export async function saveHarFiles(harFiles: HarFile[]): Promise<void> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    
    let completed = 0;
    const total = harFiles.length;
    
    if (total === 0) {
      resolve();
      return;
    }
    
    harFiles.forEach(harFile => {
      const request = store.put(harFile);
      
      request.onsuccess = () => {
        completed++;
        if (completed === total) {
          resolve();
        }
      };
      
      request.onerror = () => {
        reject(new Error(`保存文件 ${harFile.name} 失败`));
      };
    });
  });
}

/**
 * 根据 ID 获取 HAR 文件
 */
export async function getHarFile(id: string): Promise<HarFile | null> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readonly');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.get(id);
    
    request.onsuccess = () => {
      resolve(request.result || null);
    };
    
    request.onerror = () => {
      reject(new Error('获取文件失败'));
    };
  });
}

/**
 * 获取所有 HAR 文件
 */
export async function getAllHarFiles(): Promise<HarFile[]> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readonly');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.getAll();
    
    request.onsuccess = () => {
      resolve(request.result || []);
    };
    
    request.onerror = () => {
      reject(new Error('获取文件列表失败'));
    };
  });
}

/**
 * 根据名称搜索 HAR 文件
 */
export async function searchHarFilesByName(name: string): Promise<HarFile[]> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readonly');
    const store = transaction.objectStore(STORE_NAME);
    const index = store.index('name');
    const request = index.getAll();
    
    request.onsuccess = () => {
      const allFiles = request.result || [];
      const filteredFiles = allFiles.filter(file => 
        file.name.toLowerCase().includes(name.toLowerCase())
      );
      resolve(filteredFiles);
    };
    
    request.onerror = () => {
      reject(new Error('搜索文件失败'));
    };
  });
}

/**
 * 根据上传时间范围获取 HAR 文件
 */
export async function getHarFilesByDateRange(
  startDate: Date, 
  endDate: Date
): Promise<HarFile[]> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readonly');
    const store = transaction.objectStore(STORE_NAME);
    const index = store.index('uploadTime');
    const range = IDBKeyRange.bound(startDate, endDate);
    const request = index.getAll(range);
    
    request.onsuccess = () => {
      resolve(request.result || []);
    };
    
    request.onerror = () => {
      reject(new Error('按日期获取文件失败'));
    };
  });
}

/**
 * 删除 HAR 文件
 */
export async function deleteHarFile(id: string): Promise<void> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.delete(id);
    
    request.onsuccess = () => {
      resolve();
    };
    
    request.onerror = () => {
      reject(new Error('删除文件失败'));
    };
  });
}

/**
 * 批量删除 HAR 文件
 */
export async function deleteHarFiles(ids: string[]): Promise<void> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    
    let completed = 0;
    const total = ids.length;
    
    if (total === 0) {
      resolve();
      return;
    }
    
    ids.forEach(id => {
      const request = store.delete(id);
      
      request.onsuccess = () => {
        completed++;
        if (completed === total) {
          resolve();
        }
      };
      
      request.onerror = () => {
        reject(new Error(`删除文件 ${id} 失败`));
      };
    });
  });
}

/**
 * 清空所有 HAR 文件
 */
export async function clearAllHarFiles(): Promise<void> {
  const database = await getDatabase();
  
  return new Promise((resolve, reject) => {
    const transaction = database.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.clear();
    
    request.onsuccess = () => {
      resolve();
    };
    
    request.onerror = () => {
      reject(new Error('清空文件失败'));
    };
  });
}

/**
 * 获取存储统计信息
 */
export async function getStorageStats(): Promise<{
  totalFiles: number;
  totalSize: number;
  oldestFile?: Date;
  newestFile?: Date;
}> {
  const files = await getAllHarFiles();
  
  if (files.length === 0) {
    return {
      totalFiles: 0,
      totalSize: 0
    };
  }
  
  const totalSize = files.reduce((sum, file) => sum + file.size, 0);
  const uploadTimes = files.map(file => file.uploadTime).sort();
  
  return {
    totalFiles: files.length,
    totalSize,
    oldestFile: uploadTimes[0],
    newestFile: uploadTimes[uploadTimes.length - 1]
  };
}

/**
 * 检查存储空间使用情况
 */
export async function checkStorageQuota(): Promise<{
  used: number;
  available: number;
  percentage: number;
}> {
  if (!navigator.storage || !navigator.storage.estimate) {
    throw new Error('浏览器不支持存储配额查询');
  }
  
  const estimate = await navigator.storage.estimate();
  const used = estimate.usage || 0;
  const available = estimate.quota || 0;
  const percentage = available > 0 ? (used / available) * 100 : 0;
  
  return {
    used,
    available,
    percentage
  };
}

/**
 * 导出所有数据
 */
export async function exportAllData(): Promise<Blob> {
  const files = await getAllHarFiles();
  const exportData = {
    version: '1.0',
    exportedAt: new Date().toISOString(),
    files
  };
  
  return new Blob([JSON.stringify(exportData, null, 2)], {
    type: 'application/json'
  });
}

/**
 * 导入数据
 */
export async function importData(blob: Blob): Promise<{
  imported: number;
  errors: string[];
}> {
  const text = await blob.text();
  const data = JSON.parse(text);
  
  if (!data.files || !Array.isArray(data.files)) {
    throw new Error('无效的导入数据格式');
  }
  
  const errors: string[] = [];
  let imported = 0;
  
  for (const file of data.files) {
    try {
      // 生成新的 ID 避免冲突
      const newFile = {
        ...file,
        id: generateId(),
        uploadTime: new Date()
      };
      
      await saveHarFile(newFile);
      imported++;
    } catch (error) {
      errors.push(`导入文件 ${file.name} 失败: ${error}`);
    }
  }
  
  return { imported, errors };
}

/**
 * 生成唯一 ID
 */
function generateId(): string {
  return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
